home *** CD-ROM | disk | FTP | other *** search
-
- /* GraphClass by Marc Le Douarain */
- /* based on example by Stefan Stuntz */
-
-
- /*
- ** This is the instance data for our custom class.
- */
-
- struct GraphClassData
- {
- struct Str_AffiTraceGraph * GraphData;
- };
-
- #define SHOW_GRAPH 0x8022
-
- void PrepCoeffForY(struct Str_AffiTraceGraph * Gfx,double ValMini,double ValMaxi,int YMini,int YMaxi)
- {
- double a,b;
- a=(double)(YMaxi-YMini)/(double)(ValMaxi-ValMini);
- b=YMini-(a*ValMini);
- Gfx->CoeffAY=a;
- Gfx->CoeffBY=b;
- }
- int ConvertYValueToPix(struct Str_AffiTraceGraph *Gfx,double Val)
- {
- int resY;
- resY=(int)(Gfx->CoeffAY*Val+Gfx->CoeffBY);
- return(resY);
- }
-
- void PrepCoeffForX(struct Str_AffiTraceGraph * Gfx,time_t ValMini,time_t ValMaxi,int XMini,int XMaxi)
- {
- double a,b;
- a=(double)(XMaxi-XMini)/(double)(ValMaxi-ValMini);
- b=XMini-(a*ValMini);
- Gfx->CoeffAX=a;
- Gfx->CoeffBX=b;
- }
- int ConvertXValueToPix(struct Str_AffiTraceGraph *Gfx,time_t Val)
- {
- int resX;
- resX=(int)(Gfx->CoeffAX*Val+Gfx->CoeffBX);
- return(resX);
- }
-
- void DrawDotted(struct RastPort * rp,int x_end,int y_end)
- {
- int i,x_start,y_start,xtaille,ytaille;
- int steps;
- double c_x,c_y;
- x_start=rp->cp_x;
- y_start=rp->cp_y;
- ytaille=y_end-y_start;
- xtaille=x_end-x_start;
- if ( xtaille>=abs(ytaille) )
- {
- steps=xtaille;
- c_x=1;
- c_y=(double)(ytaille)/(double)steps;
- }
- else
- {
- steps=ytaille;
- c_y=1;
- c_x=(double)(xtaille)/(double)steps;
- }
- for(i=0;i<steps;i=i+3)
- {
- Move(rp,(int)(x_start+(double)i*c_x),(int)(y_start+(double)i*c_y));
- Draw(rp,(int)(x_start+(double)i*c_x),(int)(y_start+(double)i*c_y));
- }
- }
-
- time_t GetRound(time_t Val,time_t Pas)
- {
- time_t T;
- T=Val/Pas;
- return(T*Pas+Pas);
- }
-
- int DrawYScale(struct RastPort * rp,int PxLeft,int PxYMini,int PxYMaxi,double ValYMini,double ValYMaxi)
- {
- char tmp[50];
- char tmp2[50];
- int PxDateDeb;
- int DecalagePix;
- int DecalagePix2;
- /* SetAPen(_rp(obj),_dri(obj)->dri_Pens[HIGHLIGHTTEXTPEN]);*/
- sprintf(tmp,"%.4f",ValYMaxi);
- sprintf(tmp2,"%.4f",ValYMini);
- /* Length in pixels */
- DecalagePix=TextLength(rp,tmp,strlen(tmp));
- DecalagePix2=TextLength(rp,tmp2,strlen(tmp2));
- if (DecalagePix2>DecalagePix)
- DecalagePix=DecalagePix2;
- /* Displaying mini and maxi values for Y */
- Move(rp,PxLeft,PxYMaxi+2);
- Text(rp,tmp,strlen(tmp));
- Move(rp,PxLeft,PxYMini+4);
- Text(rp,tmp2,strlen(tmp2));
- PxDateDeb=PxLeft+DecalagePix+4;
- /* Drawing Y Axe */
- Move(rp,PxDateDeb,PxYMaxi);
- Draw(rp,PxDateDeb,PxYMini+3);
- return PxDateDeb;
- }
-
- void DrawXScale(struct RastPort * rp,struct Str_AffiTraceGraph *Gfx,int PxYMini,int PxDateDeb,int PxDateFin,time_t TpsDeb,time_t TpsFin)
- {
- time_t DiffTps;
- time_t Tab[5][3]={{24*3600,3600,1},{2*24*3600,2*3600,1},{7*24*3600,24*3600,2},{31*24*3600,24*3600,3}};
- time_t PasTps=0;
- int AffiEchelleTps=0;
- time_t TpsI;
- int i;
- /* SetAPen(_rp(obj),_dri(obj)->dri_Pens[HIGHLIGHTTEXTPEN]);*/
- /* Scale */
- Move(rp,PxDateDeb-3,PxYMini);
- Draw(rp,PxDateFin,PxYMini);
- /* Size of time */
- DiffTps=TpsFin-TpsDeb;
- PasTps=0;
- for (i=0;i<=3;i++)
- {
- if(DiffTps==Tab[i][0])
- {
- PasTps=Tab[i][1];
- AffiEchelleTps=Tab[i][2];
- }
- }
- /* Graduation */
- if (PasTps)
- {
- TpsI=GetRound(TpsDeb,PasTps);
- do
- {
- int X;
- char TmpD[20],TmpH[20],Grad[50];
- X=ConvertXValueToPix(Gfx,TpsI);
- Move(rp,X,PxYMini-2);
- Draw(rp,X,PxYMini+2);
- convert_long_to_asciidate(TpsI,TmpD,TmpH);
- if (AffiEchelleTps==1)
- {
- if (TmpH[0]!='0')
- {
- Grad[0]=TmpH[0];
- Grad[1]=TmpH[1];
- Grad[2]='\0';
- }
- else
- {
- Grad[0]=TmpH[1];
- Grad[1]='\0';
- }
- Move(rp,X-6,PxYMini+4+8);
- Text(rp,Grad,strlen(Grad));
- }
- if (AffiEchelleTps==2)
- {
- Grad[0]=TmpD[0];
- Grad[1]=TmpD[1];
- Grad[2]=TmpD[2];
- Grad[3]=TmpD[3];
- Grad[4]=TmpD[4];
- Grad[5]='\0';
- Move(rp,X+10,PxYMini+4+8);
- Text(rp,Grad,strlen(Grad));
- }
- if (AffiEchelleTps==3)
- {
- Grad[0]=TmpD[0];
- Grad[1]=TmpD[1];
- Grad[2]='\0';
- Move(rp,X+2,PxYMini+4+8);
- Text(rp,Grad,strlen(Grad));
- }
- TpsI=TpsI+PasTps;
- }
- while(TpsI<=TpsFin);
- }
- }
-
- /*
- ** OM_SET method, we need to see if someone want to display a graph.
- */
- SAVEDS ULONG mSet(struct IClass *cl,Object *obj,Msg msg)
- {
- struct GraphClassData *Data = INST_DATA(cl,obj);
- struct TagItem *tags,*tag;
-
- for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
- {
- switch (tag->ti_Tag)
- {
- case SHOW_GRAPH:
- if (tag->ti_Data)
- {
- Data->GraphData = ((struct Str_AffiTraceGraph *)tag->ti_Data);
- MUI_Redraw(obj,MADF_DRAWOBJECT); /* redraw ourselves completely */
- }
- break;
- }
- }
-
- return(DoSuperMethodA(cl,obj,msg));
- }
-
-
- /*
- ** AskMinMax method will be called before the window is opened
- ** and before layout takes place. We need to tell MUI the
- ** minimum, maximum and default size of our object.
- */
- SAVEDS ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
- {
- /*
- ** let our superclass first fill in what it thinks about sizes.
- ** this will e.g. add the size of frame and inner spacing.
- */
-
- DoSuperMethodA(cl,obj,msg);
-
- /*
- ** now add the values specific to our object. note that we
- ** indeed need to *add* these values, not just set them!
- */
-
- msg->MinMaxInfo->MinWidth += 100;
- msg->MinMaxInfo->DefWidth += 120;
- msg->MinMaxInfo->MaxWidth += 1280;
-
- msg->MinMaxInfo->MinHeight += 40;
- msg->MinMaxInfo->DefHeight += 90;
- msg->MinMaxInfo->MaxHeight += 800;
-
- return(0);
- }
-
-
- /*
- ** Draw method is called whenever MUI feels we should render
- ** our object. This usually happens after layout is finished
- ** or when we need to refresh in a simplerefresh window.
- ** Note: You may only render within the rectangle
- ** _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
- */
-
- SAVEDS ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
- {
- struct GraphClassData *Data = INST_DATA(cl,obj);
- struct Str_AffiTraceGraph *Graph;
- int i;
- int PxLeft;
- int PxDateDeb;
- int PxDateFin;
- int PxYMini;
- int PxYMaxi;
-
- double ValYMini=0;
- double ValYMaxi=0;
-
- PxLeft=_mleft(obj)+2;
- PxDateDeb=_mleft(obj)+12;
- PxDateFin=_mright(obj)-5;
- PxYMini=_mbottom(obj)-18;
- PxYMaxi=_mtop(obj)+5;
-
- Graph=Data->GraphData;
- /* Searching minis and maxis */
- if (Graph)
- {
- if (Graph->NbrSamples>0)
- {
- ValYMini=Graph->Valeurs[0];
- ValYMaxi=Graph->Valeurs[0];
- for(i=1;i<Graph->NbrSamples;i++)
- {
- if (ValYMini>Graph->Valeurs[i])
- ValYMini=Graph->Valeurs[i];
- if (ValYMaxi<Graph->Valeurs[i])
- ValYMaxi=Graph->Valeurs[i];
- }
- }
- }
-
- /*
- ** let our superclass draw itself first, area class would
- ** e.g. draw the frame and clear the whole region. What
- ** it does exactly depends on msg->flags.
- */
-
- DoSuperMethodA(cl,obj,msg);
-
- /*
- ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
- ** MUI just wanted to update the frame or something like that.
- */
-
- if (!(msg->flags & MADF_DRAWOBJECT))
- return(0);
-
- /*
- ** ok, everything ready to render...
- */
-
-
- if (Graph)
- {
- /* Drawing the scales */
- SetAPen(_rp(obj),_dri(obj)->dri_Pens[HIGHLIGHTTEXTPEN]);
- if(Graph->NbrSamples>0)
- {
- PrepCoeffForY(Graph,ValYMini,ValYMaxi,PxYMini,PxYMaxi);
- PxDateDeb=DrawYScale(_rp(obj),PxLeft,PxYMini,PxYMaxi,ValYMini,ValYMaxi);
- }
- PrepCoeffForX(Graph,AffiGraphGene.Time32Deb,AffiGraphGene.Time32Fin,PxDateDeb,PxDateFin);
- DrawXScale(_rp(obj),Graph,PxYMini,PxDateDeb,PxDateFin,AffiGraphGene.Time32Deb,AffiGraphGene.Time32Fin);
-
-
- /* Drawing the samples */
- if(Graph->NbrSamples>0)
- {
- int x,y;
- SetAPen(_rp(obj),_dri(obj)->dri_Pens[TEXTPEN]);
- // x=ConvertXValueToPix(TRUE,Graph->Horodates[0],AffiGraphGene.Time32Deb,AffiGraphGene.Time32Fin,PxDateDeb,PxDateFin);
- // y=ConvertYValueToPix(TRUE,Graph->Valeurs[0],ValYMini,ValYMaxi,PxYMini,PxYMaxi);
- x=ConvertXValueToPix(Graph,Graph->Horodates[0]);
- y=ConvertYValueToPix(Graph,Graph->Valeurs[0]);
- Move(_rp(obj),x,y);
- for (i=1;i<Graph->NbrSamples;i++)
- {
- // x=ConvertXValueToPix(FALSE,Graph->Horodates[i],Graph->Horodates[0],Graph->Horodates[Graph->NbrSamples-1],PxDateDeb,PxDateFin);
- // y=ConvertYValueToPix(FALSE,Graph->Valeurs[i],ValYMini,ValYMaxi,PxYMini,PxYMaxi);
- x=ConvertXValueToPix(Graph,Graph->Horodates[i]);
- y=ConvertYValueToPix(Graph,Graph->Valeurs[i]);
- if ( (Graph->Horodates[i]-Graph->Horodates[i-1]) <= 60*60 )
- Draw(_rp(obj),x,y);
- else
- DrawDotted(_rp(obj),x,y);
- }
- }
- }
-
- return(0);
- }
-
-
- /*
- ** Here comes the dispatcher for our custom class. We only need to
- ** care about MUIM_AskMinMax and MUIM_Draw in this simple case.
- ** Unknown/unused methods are passed to the superclass immediately.
- */
-
- #ifdef __GNUC__
- SAVEDS ASM ULONG MyDispatcher(REG(a0,struct IClass *cl),REG(a2,Object *obj),REG(a1,Msg msg))
- #else
- SAVEDS ASM ULONG MyDispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
- #endif
- {
- switch (msg->MethodID)
- {
- case OM_SET : return(mSet (cl,obj,(APTR)msg));
- case MUIM_AskMinMax : return(mAskMinMax(cl,obj,(APTR)msg));
- case MUIM_Draw : return(mDraw (cl,obj,(APTR)msg));
- }
-
- return(DoSuperMethodA(cl,obj,msg));
- }
-
-
-
-